home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / cmouse.exe / CMOUSE.CPP < prev    next >
C/C++ Source or Header  |  1991-07-27  |  11KB  |  459 lines

  1. /*
  2.  
  3.     cmouse.cpp
  4.     7-27-91
  5.     Microsoft mouse interrupt functions
  6.  
  7.     Copyright 1991
  8.     John W. Small
  9.     All rights reserved
  10.  
  11.     PSW / Power SoftWare
  12.     P.O. Box 10072
  13.     McLean, Virginia 22102 8072
  14.     (703) 759-3838
  15.  
  16.  
  17.     Works consulted:
  18.  
  19.     "Microsoft Mouse Programmer's Reference."
  20.         Bellevue, Washington: Microsoft Press, 1989.
  21.  
  22.     "Microsoft Mouse Programmer's Reference Guide."
  23.         Bellevue, Washington: Microsoft Press, 1986.
  24.  
  25.     Refer to above works for mouse function
  26.     documentation.
  27.  
  28. */
  29.  
  30.  
  31. #include <dos.h>    /* union REGS, struct SREGS, */
  32.             /*  int86(), int86x(), */
  33.             /* geninterrupt(), enable() */
  34. #include <cmouse.hpp>
  35.  
  36. MicrosoftMouse MM;    // Only instance allowed!
  37.  
  38. unsigned MicrosoftMouse::Xcell[] = {
  39.     16,16,8,8,2,2,1,8,1,1,1,1,1,2,1,1,1,1,1,2};
  40. unsigned MicrosoftMouse::Ycell[] = {
  41.     8,8,8,8,1,1,1,8,1,1,1,1,1,1,1,1,1,1,1,1};
  42. unsigned MicrosoftMouse::LeftTopOfs[] = {
  43.     1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};
  44.  
  45. void MicrosoftMouse::close()
  46. {
  47.     on();
  48.     restore();
  49.     clearAltInterrupts();
  50.     reset();
  51.     state = origState;
  52.     restore();
  53. }
  54.  
  55. /* Stack overflow check overwrites AX : do not compile with -N */
  56. /* Do not call!  Use to cookbook your own if needed. */
  57. #pragma argsused
  58. void interrupt MMautoEventHandler(
  59.     unsigned iBP,
  60.     unsigned vertMickeys,    /* di */
  61.     unsigned horzMickeys,    /* si */
  62.     unsigned iDS,
  63.     unsigned iES,
  64.     unsigned y,              /* dx */
  65.     unsigned x,              /* cx */
  66.     unsigned buttonState,    /* bx */
  67.     unsigned conditionMask,  /* ax */
  68.     unsigned iIP,
  69.     unsigned iCS,
  70.     unsigned pseudoFlags)     /* not present */
  71. {
  72.     MM.eventTime = (*(long far *)MK_FP(0x0040,0x006C));
  73.     enable();
  74.  
  75.     MM.eventCount++;
  76.     MM.eventFlags = conditionMask;
  77.     MM.leftPressed = (buttonState & MBleft)? 1 : 0;
  78.     MM.rightPressed = (buttonState & MBright)? 1 : 0;
  79.     MM.x = MM.physicalX(x);
  80.     MM.y = MM.physicalY(y);
  81.     MM.horzMickeys = horzMickeys;
  82.     MM.vertMickeys = vertMickeys;
  83.  
  84.     if (conditionMask & MEmoved)
  85.         MM.eventMoved++;
  86.     if (conditionMask & MEleftPressed)  {
  87.         MM.leftPressed = 1;
  88.         MM.lastLeftPressX = MM.x;
  89.         MM.lastLeftPressY = MM.y;
  90.         MM.leftPresses++;
  91.         MM.buttonRequested = MBleft;
  92.         if ((MM.leftClickTime > MM.eventTime) ||
  93.             ((MM.eventTime - MM.leftClickTime)
  94.             > MM.clickTimeOut))  {
  95.             MM.leftClickTime = MM.eventTime;
  96.             MM.leftClicks = 0;
  97.         }
  98.     }
  99.     if (conditionMask & MEleftReleased)  {
  100.         MM.leftPressed = 0;
  101.         MM.lastLeftReleaseX = MM.x;
  102.         MM.lastLeftReleaseY = MM.y;
  103.         MM.leftReleases++;
  104.         MM.buttonRequested = MBleft;
  105.         if ((MM.leftClickTime > MM.eventTime) ||
  106.             ((MM.eventTime - MM.leftClickTime)
  107.             > MM.clickTimeOut))  {
  108.             MM.leftClickTime = MM.eventTime;
  109.             MM.leftClicks = 0;
  110.         }
  111.         else
  112.             MM.leftClicks++;
  113.     }
  114.     if (conditionMask & MErightPressed)  {
  115.         MM.rightPressed = 1;
  116.         MM.lastRightPressX = MM.x;
  117.         MM.lastRightPressY = MM.y;
  118.         MM.rightPresses++;
  119.         MM.buttonRequested = MBright;
  120.         if ((MM.rightClickTime > MM.eventTime) ||
  121.             ((MM.eventTime - MM.rightClickTime)
  122.             > MM.clickTimeOut))  {
  123.             MM.rightClickTime = MM.eventTime;
  124.             MM.rightClicks = 0;
  125.         }
  126.     }
  127.     if (conditionMask & MErightReleased)  {
  128.         MM.rightPressed = 0;
  129.         MM.lastRightReleaseX = MM.x;
  130.         MM.lastRightReleaseY = MM.y;
  131.         MM.rightReleases++;
  132.         MM.buttonRequested = MBright;
  133.         if ((MM.rightClickTime > MM.eventTime) ||
  134.             ((MM.eventTime - MM.rightClickTime)
  135.             > MM.clickTimeOut))  {
  136.             MM.rightClickTime = MM.eventTime;
  137.             MM.rightClicks = 0;
  138.         }
  139.         else
  140.             MM.rightClicks++;
  141.     }
  142.  
  143. /*
  144.     Convert from Interrupt stack frame to FAR call stack
  145.     frame then return from FAR.  Since the mouse driver
  146.     FAR calls this interrupt handler instead of issuing
  147.     an interrupt call to get here, this event handler
  148.     needs to return from a FAR call instead of returning
  149.     from an interrupt!  A Turbo C++    interrupt function
  150.     was used since it automatically restores DS to the
  151.     data segment.  The mouse driver also passes
  152.     parameters in registers instead of on the
  153.     stack.  TC++'s interrupt keyword forces the function
  154.     to automatically stack these registers so that they
  155.     can be accessed.
  156. */
  157.  
  158.     asm mov ax,iDS       /* restore DS */
  159.     asm mov ds,ax
  160.  
  161.     conditionMask = iBP; /* skip over parameters */
  162.     asm add bp,16        /* OFFSET conditionMask */
  163.  
  164.     asm mov sp,bp        /* exit far proc */
  165.     asm pop bp
  166.     asm retf
  167. }
  168.  
  169. void MicrosoftMouse::open()
  170. {
  171.     unsigned char far *vec;
  172.  
  173.     vmode = 0;
  174.     present = 0;
  175.     buttons = 0;
  176.     leftPressed = 0; rightPressed = 0;
  177.     x = 0; y = 0;
  178.     lastLeftPressX = 0; lastLeftPressY = 0;
  179.     leftPresses = 0;
  180.     buttonRequested = MBleft;
  181.     lastLeftReleaseX = 0; lastLeftReleaseY = 0;
  182.     leftReleases = 0;
  183.     lastRightPressX = 0; lastRightPressY = 0;
  184.     rightPresses = 0;
  185.     lastRightReleaseX = 0; lastRightReleaseY = 0;
  186.     rightReleases = 0;
  187.     vertMickeys= 0; horzMickeys = 0;
  188.     handler = (MouseHandler) 0;
  189.     callMask = 0;
  190.     eventMask = 0x001F;
  191.     eventFlags = 0;
  192.     eventCount = 0;
  193.     eventMoved = 0;
  194.     eventTime = 0;
  195.     clickTimeOut = 10;
  196.     leftClickTime = 0;
  197.     leftClicks = 0;
  198.     rightClickTime = 0;
  199.     rightClicks = 0;
  200.     origState = (void *) 0;
  201.     state = (void *) 0;
  202.     stateSize = 0;
  203.     altHandler = (MouseHandler) 0;
  204.     altCallMask = 0;
  205.     horzPercent = 50; vertPercent = 50;
  206.     doublePercent = 50;
  207.     crtPage = 0;
  208.     mouseIntrVector = (MouseDriver) 0;
  209.     language = MLenglish;
  210.     driverVersion = 0;
  211.     IRQ = -1;
  212.     typeRequired = MTunknown;
  213.     vec = (unsigned char far *) getvect(MOUSE_INT);
  214.     if (!vec || (*vec == 0xCF)) /* IRET */
  215.         return;
  216.     reset();
  217.     driver();
  218.     if (!present)
  219.         return;
  220.     save();
  221.     origState = state;
  222.     state = (void *) 0;
  223. }
  224.  
  225. void MicrosoftMouse::reset()            /* MF0 */
  226. {
  227.     _AH = 0x0F;
  228.     geninterrupt(0x10);
  229.     vmode = _AL;
  230.     _AX = 0;
  231.     geninterrupt(MOUSE_INT);
  232.     if (_AX) {
  233.         buttons = _BX;
  234.         present = 1;
  235.     }
  236.     else
  237.         buttons = present = 0;
  238. }
  239.  
  240. void MicrosoftMouse::updateStatusInfo()        /* MF3 */
  241. {
  242.     unsigned buttons;
  243.  
  244.     _AX = 3;
  245.     geninterrupt(MOUSE_INT);
  246.     buttons = _BX;
  247.     x = _CX;
  248.     y = _DX;
  249.     leftPressed = (buttons & MBleft)? 1 : 0;
  250.     rightPressed = (buttons & MBright)? 1 : 0;
  251.     x = physicalX(x);
  252.     y = physicalY(y);
  253. }
  254.  
  255. void MicrosoftMouse::gotoxy()            /* MF4 */
  256. {
  257.     unsigned vx, vy;
  258.  
  259.     vx = virtualX(x);
  260.     vy = virtualY(y);
  261.     _CX = vx;
  262.     _DX = vy;
  263.     _AX = 4;
  264.     geninterrupt(MOUSE_INT);
  265. }
  266.  
  267. void MicrosoftMouse::updatePressInfo()        /* MF5 */
  268. {
  269.     union REGS rgs;
  270.  
  271.     rgs.x.ax = 5;
  272.     rgs.x.bx = buttonRequested >> 1;
  273.     (void) int86(MOUSE_INT,&rgs,&rgs);
  274.     leftPressed = (rgs.x.ax & MBleft)? 1 : 0;
  275.     rightPressed = (rgs.x.ax & MBright)? 1 : 0;
  276.     if (buttonRequested == MBleft)  {
  277.         leftPresses = rgs.x.bx;
  278.         lastLeftPressX = physicalX(rgs.x.cx);
  279.         lastLeftPressY = physicalY(rgs.x.dx);
  280.     }
  281.     else {
  282.         rightPresses = rgs.x.bx;
  283.         lastRightPressX = physicalX(rgs.x.cx);
  284.         lastRightPressY = physicalY(rgs.x.dx);
  285.     }
  286. }
  287.  
  288. void MicrosoftMouse::updateReleaseInfo()    /* MF6 */
  289. {
  290.     union REGS rgs;
  291.  
  292.     rgs.x.ax = 6;
  293.     rgs.x.bx = buttonRequested >> 1;
  294.     (void) int86(MOUSE_INT,&rgs,&rgs);
  295.     leftPressed = (rgs.x.ax & MBleft)? 1 : 0;
  296.     rightPressed = (rgs.x.ax & MBright)? 1 : 0;
  297.     if (buttonRequested == MBleft)  {
  298.         leftReleases = rgs.x.bx;
  299.         lastLeftReleaseX = physicalX(rgs.x.cx);
  300.         lastLeftReleaseY = physicalY(rgs.x.dx);
  301.     }
  302.     else {
  303.         rightReleases = rgs.x.bx;
  304.         lastRightReleaseX = physicalX(rgs.x.cx);
  305.         lastRightReleaseY = physicalY(rgs.x.dx);
  306.     }
  307. }
  308.  
  309. void MicrosoftMouse::trap(unsigned x1, unsigned y1,
  310.     unsigned x2, unsigned y2)
  311. {                        /* MF7, MF8 */
  312.     unsigned d1, d2;
  313.  
  314.     d1 = virtualX(x1);
  315.     d2 = virtualX(x2);
  316.     _CX = d1;
  317.     _DX = d2;
  318.     _AX = 7;
  319.     geninterrupt(MOUSE_INT);
  320.     d1 = virtualY(y1);
  321.     d2 = virtualY(y2);
  322.     _CX = d1;
  323.     _DX = d2;
  324.     _AX = 8;
  325.     geninterrupt(MOUSE_INT);
  326. }
  327.  
  328. void MicrosoftMouse::graphicsCursor(signed char horzHS,
  329.     signed char vertHS,
  330.     unsigned far *scrCurMask)               /* MF9 */
  331. {
  332.     unsigned h, v;
  333.  
  334.     h = ((unsigned) horzHS) * Xcell[vmode];
  335.     v = ((unsigned) vertHS) * Ycell[vmode];
  336.     _ES = FP_SEG(scrCurMask);
  337.     _DX = FP_OFF(scrCurMask);
  338.     _BX = h;
  339.     _CX = v;
  340.     _AX = 9;
  341.     geninterrupt(MOUSE_INT);
  342. }
  343.  
  344. void MicrosoftMouse::swapInterrupts()        /* MF20 */
  345. {
  346.     union REGS rgs;
  347.     struct SREGS srgs;
  348.  
  349.     rgs.x.ax = 20;
  350.     rgs.x.cx = callMask;
  351.     rgs.x.dx = FP_OFF(handler);
  352.     srg